package cn.com.dcsgo.service.impl;

import cn.com.dcsgo.constant.CacheConstant;
import cn.com.dcsgo.dto.CategoryAddDTO;
import cn.com.dcsgo.dto.CategoryUpdateDTO;
import cn.com.dcsgo.exception.BusinessException;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.com.dcsgo.domain.Category;
import cn.com.dcsgo.service.CategoryService;
import cn.com.dcsgo.mapper.CategoryMapper;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * 针对表【category(产品类目)】的数据库操作Service实现
 *
 * @author Dcsgo
 * @since 2025-10-14 08:45:29
 */
@Service
@CacheConfig(cacheNames = "cn.com.dcsgo.service.impl.CategoryServiceImpl")
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category>
        implements CategoryService {

    @Override
    @Cacheable(key = CacheConstant.ALL_CATEGORY)
    public List<Category> getOrderedCategoryTable() {
        return baseMapper.selectList(
                new LambdaQueryWrapper<Category>()
                        .orderByAsc(Category::getParentId, Category::getSeq)
        );
    }

    @Override
    @Cacheable(key = CacheConstant.ALL_NORMAL_CATEGORY)
    public List<Category> getOrderedNormalCategoryList() {
        return baseMapper.selectList(
                new LambdaQueryWrapper<Category>()
                        .eq(Category::getStatus, 1)
                        .orderByAsc(Category::getParentId, Category::getSeq)
        );
    }

    @Override
    @Caching(evict = {
            @CacheEvict(key = CacheConstant.ALL_CATEGORY),
            @CacheEvict(key = CacheConstant.ALL_NORMAL_CATEGORY),
    })
    public boolean addCategory(CategoryAddDTO categoryAddDTO) {
        // 分类名不能重复
        Category category = baseMapper.selectOne(
                new LambdaQueryWrapper<Category>()
                        .eq(Category::getCategoryName, categoryAddDTO.getCategoryName())
        );
        if (category != null) {
            throw new BusinessException("分类名【" + category.getCategoryName() + "】已存在");
        }
        // 父分类必须存在（新增一级分类（父分类ID为0）除外）
        if (categoryAddDTO.getParentId() == null
                || categoryAddDTO.getParentId().equals(0L)) {
            categoryAddDTO.setParentId(0L);
        } else {
            category = baseMapper.selectById(categoryAddDTO.getParentId());
            if (category == null) {
                throw new BusinessException("父分类不存在");
            }
        }
        category = new Category();
        BeanUtil.copyProperties(categoryAddDTO, category);
        category.setCreateTime(new Date());
        int row = baseMapper.insert(category);
        return row > 0;
    }

    @Override
    @Caching(evict = {
            @CacheEvict(key = CacheConstant.ALL_CATEGORY),
            @CacheEvict(key = CacheConstant.ALL_NORMAL_CATEGORY),
    })
    public boolean updateById(CategoryUpdateDTO categoryUpdateDTO) {
        //1.更新分类存在
        //2.新分类名不能重复
        //3.父分类必须存在（更新为一级分类->父分类ID为0除外）
        //4.状态更新为下线时，必须保证该分类下没有正常状态的子分类

        // 拿到老的分类信息
        Category oldData = baseMapper.selectById(categoryUpdateDTO.getCategoryId());
        if (oldData == null) {
            throw new BusinessException("更新分类不存在");
        }
        // 分类名不能重复
        if (categoryUpdateDTO.getCategoryName() != null
                && !oldData.getCategoryName().equals(categoryUpdateDTO.getCategoryName())) {
            Category selected = baseMapper.selectOne(
                    new LambdaQueryWrapper<Category>()
                            .eq(Category::getCategoryName, categoryUpdateDTO.getCategoryName())
            );
            if (selected != null) {
                throw new BusinessException("分类名【" + categoryUpdateDTO.getCategoryName() + "】已存在");
            }
        }
        // 父分类必须存在（更新为一级分类->父分类ID为0除外）
        if (categoryUpdateDTO.getParentId() != null
                && !categoryUpdateDTO.getParentId().equals(oldData.getParentId())) {
            if (oldData.getCategoryId().equals(categoryUpdateDTO.getParentId())) {
                throw new BusinessException("不能将自己设为父分类");
            }
            if (!categoryUpdateDTO.getParentId().equals(0L)) {
                Category selected = baseMapper.selectOne(
                        new LambdaQueryWrapper<Category>()
                                .eq(Category::getCategoryId, categoryUpdateDTO.getParentId())
                );
                if (selected == null) {
                    throw new BusinessException("父分类不存在");
                }
            }
        }
        // 状态更新为下线时，必须保证该分类下没有正常状态的子分类
        if (categoryUpdateDTO.getStatus() != null
                && !categoryUpdateDTO.getStatus().equals(oldData.getStatus())
                && categoryUpdateDTO.getStatus().equals(0)) {
            boolean exists = baseMapper.exists(
                    new LambdaQueryWrapper<Category>()
                            .eq(Category::getParentId, categoryUpdateDTO.getCategoryId())
                            .eq(Category::getStatus, 1)
            );
            if (exists) {
                throw new BusinessException("该分类下存在正常状态的子分类，不能将状态更新为下线");
            }
        }
        Category saveData = new Category();
        BeanUtil.copyProperties(categoryUpdateDTO, saveData);
        saveData.setUpdateTime(new Date());
        int row = baseMapper.updateById(saveData);
        return row > 0;
    }

    @Override
    @Caching(evict = {
            @CacheEvict(key = CacheConstant.ALL_CATEGORY),
            @CacheEvict(key = CacheConstant.ALL_NORMAL_CATEGORY),
    })
    public boolean carefulRemoveById(Long categoryId) {
        Category selected = baseMapper.selectOne(
                new LambdaQueryWrapper<Category>()
                        .eq(Category::getCategoryId, categoryId)
        );
        if (selected == null) {
            throw new BusinessException("分类不存在");
        }
        if (selected.getStatus().equals(1)) {
            throw new BusinessException("不能删除状态为正常的分类");
        }
        boolean exists = baseMapper.exists(
                new LambdaQueryWrapper<Category>()
                        .eq(Category::getParentId, categoryId)
        );
        if (exists) {
            throw new BusinessException("该分类下存在子分类，不允许删除");
        }
        int row = baseMapper.deleteById(categoryId);
        return row > 0;
    }
}




